
package com.jf.cloud.coupon.feign;

import cn.hutool.core.collection.CollectionUtil;
import com.jf.cloud.api.coupon.dto.ChooseCouponDTO;
import com.jf.cloud.api.coupon.dto.LockCouponDTO;
import com.jf.cloud.api.coupon.dto.PlatformChooseCouponDTO;
import com.jf.cloud.api.coupon.feign.CouponOrderFeignClient;
import com.jf.cloud.common.order.vo.*;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.coupon.service.CouponLockService;
import com.jf.cloud.coupon.service.CouponService;
import com.jf.cloud.coupon.util.ChooseCouponHelper;
import ma.glasnost.orika.MapperFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Hidden;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zz
 * @date 2020/12/17
 */
@RestController
@Hidden
public class CouponOrderFeignController implements CouponOrderFeignClient {
    private final Logger LOGGER = LoggerFactory.getLogger(CouponOrderFeignController.class);

    @Autowired
    private CouponService couponService;
    @Autowired
    private CouponLockService couponLockService;
    @Autowired
    private MapperFacade mapperFacade;

    @Override
    public ServerResponseEntity<List<ShopCartVO>> chooseShopCoupon(ChooseCouponDTO param) {
        Long userId = AuthUserContext.get().getUserId();

        List<ShopCartVO> shopCarts = param.getShopCarts();

        for (ShopCartVO shopCart : shopCarts) {
            List<ShopCartItemDiscountVO> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts();
            List<ShopCartItemVO> shopCartItems = new ArrayList<>();
            for (ShopCartItemDiscountVO shopCartItemDiscount : shopCartItemDiscounts) {
                shopCartItems.addAll(shopCartItemDiscount.getShopCartItems());
            }
            // 因为经过满减，实际金额的顺序已经变了
            shopCartItems = shopCartItems.stream().sorted(Comparator.comparingDouble(ShopCartItemVO::getActualTotal)).collect(Collectors.toList());

            // 获取用户有效的优惠券
            List<CouponOrderVO> shopCoupons = couponService.getCouponListByUserIdAndShopId(userId, shopCart.getShopId());

            // 用户选中的所有优惠券
            List<Long> couponIds = param.getCouponIds();

            Integer userChangeCoupon = param.getUserChangeCoupon();

            ChooseCouponHelper chooseCouponHelper = new ChooseCouponHelper(shopCartItems, shopCoupons, couponIds, userChangeCoupon).invoke();

            if (chooseCouponHelper.getChooseCoupon() != null) {
                LOGGER.info("用户选择的优惠券：{}", chooseCouponHelper.getChooseCoupon());
                long couponReduce = chooseCouponHelper.getCouponReduce();
                // 最后组装订单信息
                shopCart.setCouponReduce(couponReduce);
                shopCart.setActualTotal(shopCart.getActualTotal() - shopCart.getCouponReduce());
                shopCart.setShopReduce(shopCart.getShopReduce() + shopCart.getCouponReduce());
            }

            shopCart.setCoupons(shopCoupons);
        }
        return ServerResponseEntity.success(shopCarts);
    }

    @Override
    public ServerResponseEntity<ShopCartOrderMergerVO> choosePlatformCoupon(PlatformChooseCouponDTO param) {
        Long userId = AuthUserContext.get().getUserId();
        ShopCartOrderMergerVO shopCartOrderMergerVO = param.getShopCartOrderMergerVO();

        // 获取用户可用平台优惠券
        List<CouponOrderVO> couponList = couponService.getCouponListByUserIdAndShopId(userId, 0L);
        if (CollectionUtil.isEmpty(couponList)) {
            return ServerResponseEntity.success(shopCartOrderMergerVO);
        }

        // 完整的订单信息
        // 订单项目
        List<ShopCartItemVO> shopAllShopCartItems = new ArrayList<>();
        List<ShopCartOrderVO> shopCartOrders = shopCartOrderMergerVO.getShopCartOrders();
        for (ShopCartOrderVO shopCartOrder : shopCartOrders) {
            List<ShopCartItemDiscountVO> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts();
            for (ShopCartItemDiscountVO shopCartItemDiscount : shopCartItemDiscounts) {
                shopAllShopCartItems.addAll(shopCartItemDiscount.getShopCartItems());
            }
        }
        // 因为经过满减，实际金额的顺序已经变了
        shopAllShopCartItems = shopAllShopCartItems.stream().sorted(Comparator.comparingDouble(ShopCartItemVO::getActualTotal)).collect(Collectors.toList());

        ChooseCouponHelper chooseCouponHelper = new ChooseCouponHelper(shopAllShopCartItems, couponList, param.getCouponIds(), param.getUserChangeCoupon()).invoke();


        if (chooseCouponHelper.getChooseCoupon() != null) {
            Long couponReduce = chooseCouponHelper.getCouponReduce();
            Map<Long, Long> shopReduceMap = chooseCouponHelper.getShopReduceMap();
            for (ShopCartOrderVO shopCartOrder : shopCartOrders) {
                Long couponAmount = shopReduceMap.get(shopCartOrder.getShopId());
                shopCartOrder.setPlatformCouponReduce(couponAmount);
                couponAmount = Objects.isNull(shopCartOrder.getPlatformAmount()) ? couponAmount :shopCartOrder.getPlatformAmount() + couponAmount;
                shopCartOrder.setPlatformAmount(couponAmount);
                shopCartOrder.setActualTotal(shopCartOrder.getActualTotal() - shopCartOrder.getPlatformCouponReduce());
                shopCartOrder.setShopReduce(shopCartOrder.getShopReduce() + shopCartOrder.getPlatformCouponReduce());
            }
            shopCartOrderMergerVO.setOrderReduce(shopCartOrderMergerVO.getOrderReduce() +  couponReduce);
            shopCartOrderMergerVO.setActualTotal(shopCartOrderMergerVO.getActualTotal() - couponReduce);
        }
        shopCartOrderMergerVO.setCoupons(couponList);
        return ServerResponseEntity.success(shopCartOrderMergerVO);
    }

    @Override
    public ServerResponseEntity<Void> lockCoupon(List<LockCouponDTO> lockCouponParams) {
        if (CollectionUtil.isEmpty(lockCouponParams)) {
            return ServerResponseEntity.success();
        }
        return couponLockService.lockCoupon(lockCouponParams);
    }

}
